Vue3 自定义指令

MuYan2024-03-03VueVue

使用 lodash-es,自定义一个全局的 click 防抖节流指令

import type { App } from "vue";
import { debounce, throttle } from "lodash-es";

/**
 * 防抖,在短时间内连续触发的事件,确保只有最后一次操作被执行
 */
const clickDebounce = {
  mounted(el: any, binding: any) {
    const { arg } = binding;
    const times = Number(arg || 1000);
    const handleClickOutside = debounce((event: any) => {
      if (el.contains(event.target)) {
        binding.value();
      }
    }, times);
    // 添加事件监听器
    document.addEventListener("click", handleClickOutside);
    // 在元素销毁时移除事件监听器
    el._clickOutsideHandler = handleClickOutside;
  },
  // 在元素被卸载时调用
  unmounted(el: any) {
    // 移除事件监听器
    document.removeEventListener("click", el._clickOutsideHandler);
  },
};

/**
 * 节流,在指定时间内,事件处理函数最多只执行一次
 */
const clickThrottle = {
  mounted(el: any, binding: any) {
    const { arg } = binding;
    const times = Number(arg || 1000);
    const handleClickOutside = throttle(
      (event: any) => {
        if (el.contains(event.target)) {
          binding.value();
        }
      },
      times,
      {
        // 最后不执行
        trailing: false,
      }
    );
    // 添加事件监听器
    document.addEventListener("click", handleClickOutside);
    // 在元素销毁时移除事件监听器
    el._clickOutsideHandler = handleClickOutside;
  },
  // 在元素被卸载时调用
  unmounted(el: any) {
    // 移除事件监听器
    document.removeEventListener("click", el._clickOutsideHandler);
  },
};

export default {
  install: (app: App) => {
    app.directive("debounce", clickDebounce);
    app.directive("throttle", clickThrottle);
  },
};

使用

// 使用
<div v-throttle="clickFun">
  节流按钮
</div>
<div v-debounce="clickFun">
  防抖按钮
</div>

// 自定义间隔
<div v-throttle:5000="clickFun">
  节流按钮
</div>
<div v-debounce:5000="clickFun">
  防抖按钮
</div>

const clickFun = () => {
  console.log('clickFun===>');
};
上次更新 2026/6/23 11:49:15
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.15.8
本页目录